package fti.uksw.ruang;

import java.sql.Date;
import java.util.ArrayList;
import java.util.Iterator;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.view.ActionProvider;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBar.OnNavigationListener;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Toast;
import fti.uksw.ruang.fragment.DayViewFragment;
import fti.uksw.ruang.fragment.MonthViewFragment;
import fti.uksw.ruang.model.CalendarEvent;
import fti.uksw.ruang.model.CalendarList;
import fti.uksw.ruang.model.Dosen;
import fti.uksw.ruang.model.Guest;
import fti.uksw.ruang.model.Login;
import fti.uksw.ruang.model.MsgCode;
import fti.uksw.ruang.model.Pengguna;
import fti.uksw.ruang.model.RecurringDetail;
import fti.uksw.ruang.websocket.ClientListener;
import fti.uksw.ruang.websocket.WebSocketClient;

public class CalViewAct extends ActionBarActivity implements
		MonthViewFragment.OnMonthViewListener,
		DayViewFragment.OnDayViewListener, ClientListener {

	public static String TAG = CalViewAct.class.getName();
	public static String TAG_SELECTED_VIEW = "TAGSELECTEDVIEW";
	public static String TAG_SELECTED_ROOM = "TAGSELECTEDROOM";
	public static String TAG_LIST_ROOM = "TAGLISTROOM";
	public static String TAG_LISTKEG = "TAGLISTKEG";

	private static int REQ_CODE_LISTROOM = 101;
	private static int REQ_CODE_EVENT = 201;

	FragmentManager fm;
	FragmentTransaction ft;
	ActionBar ab;

	private MenuItem menuItemRoom;

	private WebSocketClient wsClient = LoginActivity.wsClient;

	private ArrayList<CalendarList> calList;
	private ArrayList<CalendarEvent> eventList;
	private ArrayList<Dosen> listDosen;

	private String idSelectedCalList = "-1";
	private int idSelectedView = 0;

	private Login login;

	SharedPreferences prefs;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.cal_view);

		login = (Login) getIntent().getExtras().get(Login.TAG);

		ab = getSupportActionBar();
		ab.setTitle("Lab's Calendar");
		ab.setDisplayShowTitleEnabled(false);
		ab.setDisplayShowHomeEnabled(false);
		ab.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
		ab.show();

		ab.setListNavigationCallbacks(ArrayAdapter.createFromResource(this,
				R.array.list_menu_calendar,
				R.layout.support_simple_spinner_dropdown_item),
				listMenuCalNavListener);

		wsClient.addListener(this);
		sendRequestRoomToServer();
//		sendRequestDosen();

		prefs = getSharedPreferences("CalView", Context.MODE_PRIVATE);
		idSelectedCalList = prefs.getString(TAG_SELECTED_ROOM, "-1");
		idSelectedView = prefs.getInt(TAG_SELECTED_VIEW, 0);
		ab.setSelectedNavigationItem(idSelectedView);

	}

	@Override
	protected void onSaveInstanceState(Bundle outState) {
		super.onSaveInstanceState(outState);
		outState.putInt(TAG_SELECTED_VIEW, ab.getSelectedNavigationIndex());
		outState.putString(TAG_SELECTED_ROOM, idSelectedCalList);
	}

	ActionProvider mActionProvider;

	public boolean onCreateOptionsMenu(Menu menu) {
		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.menu.cal_view_menu, menu);
		menuItemRoom = menu.findItem(R.id.action_room);
		return super.onCreateOptionsMenu(menu);
	}

	@Override
	public boolean onPrepareOptionsMenu(Menu menu) {
		if (calList != null) {

			String mTitle = "";

			for (CalendarList _cl : calList) {
				if (_cl.getCalendarId().equals(idSelectedCalList)) {
					mTitle = _cl.getCalendarTitle();
					break;
				}
			}

			if (mTitle.length() > MAX_STR_LENGTH) {
				mTitle = mTitle.substring(0, MAX_STR_LENGTH) + "...";
			} else {
			}
			menuItemRoom.setTitle(mTitle);
		}
		return super.onPrepareOptionsMenu(menu);
	}

	public boolean onOptionsItemSelected(MenuItem item) {

		if (item.getItemId() == R.id.action_new) {
			Intent intentAddEvent = new Intent(this, NewItemAct.class);
			intentAddEvent.putExtra(Login.TAG, login);
//			intentAddEvent.putExtra(CalendarList.TAG, calList);
//			intentAddEvent.putExtra(Dosen.TAG, listDosen);
			startActivity(intentAddEvent);
			finish();
		} else if (item.getItemId() == R.id.action_room) {

			Intent intentListRoom = new Intent(this, ListRoomActivity.class);
//			intentListRoom.putExtra(TAG_LIST_ROOM, calList);
			startActivityForResult(intentListRoom, REQ_CODE_LISTROOM);
		}
		return true;
	}

	private static final int MAX_STR_LENGTH = 12;

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		if (requestCode == REQ_CODE_LISTROOM) {
			if (resultCode == RESULT_OK) {
				CalendarList calList = data
						.getParcelableExtra(ListRoomActivity.SELECTED_ROOM);
				idSelectedCalList = calList.getCalendarId();
				supportInvalidateOptionsMenu();
				sendReqEventByRoom(idSelectedCalList);

				Editor edit = prefs.edit();
				edit.putString(TAG_SELECTED_ROOM, idSelectedCalList);
				edit.commit();
			}
		} else if (requestCode == REQ_CODE_EVENT) {
			sendReqEventByRoom(idSelectedCalList);
		}
	}

	private MonthViewFragment monthViewFragment;
	private DayViewFragment dayViewFragment;

	private OnNavigationListener listMenuCalNavListener = new OnNavigationListener() {

		@Override
		public boolean onNavigationItemSelected(int itemPosition, long itemId) {

			sendReqEventByRoom(idSelectedCalList);
			// updateListKegMonthView();
			switch (itemPosition) {
			case 0:
				monthViewFragment = new MonthViewFragment();
				manageFragment(monthViewFragment, MonthViewFragment.TAG);
				break;
			case 1:
				dayViewFragment = new DayViewFragment();
				manageFragment(dayViewFragment, DayViewFragment.TAG);
				break;
			}
			Editor edit = prefs.edit();
			edit.putInt(TAG_SELECTED_VIEW, itemPosition);
			edit.commit();
			return false;
		}
	};

	@Override
	public void onMontViewEventClick(ArrayList<CalendarEvent> mListKeg) {
		if (mListKeg != null) {
			wsClient.removeListener(this);
			Intent intentListKeg = new Intent(getApplicationContext(),
					ListKegActivity.class);
			intentListKeg.putExtra(CalendarEvent.TAG, mListKeg);
			intentListKeg.putExtra(Login.TAG, login);
			startActivityForResult(intentListKeg, REQ_CODE_EVENT);
			finish();
		}
	}

	@Override
	public void onDayViewEventClick(ArrayList<CalendarEvent> mListKeg) {
		if (mListKeg != null) {
			wsClient.removeListener(this);
			Intent intentListKeg = new Intent(getApplicationContext(),
					ListKegActivity.class);
			intentListKeg.putExtra(CalendarEvent.TAG, mListKeg);
			intentListKeg.putExtra(Login.TAG, login);
			startActivityForResult(intentListKeg, REQ_CODE_EVENT);
			finish();
		}
	}
	@Override
	public void onCalendarMonthChanged(String detail) {
	}

	private void sendRequestRoomToServer() {
		JSONObject msg = new JSONObject();
		try {
			msg.put(MsgCode.MSGCODE, MsgCode.CALENDARLISTREQ);
		} catch (JSONException e) {
			e.printStackTrace();
		}
		wsClient.sendTextMessage(msg.toString());
	}

	private void sendRequestDosen() {
		JSONObject msgReq = new JSONObject();
		try {
			msgReq.put(MsgCode.MSGCODE, MsgCode.DOSENREQ);
			wsClient.sendTextMessage(msgReq.toString());
		} catch (JSONException e) {
			e.printStackTrace();
		}
	}

	private void manageFragment(Fragment fragment, String tag) {
		FragmentManager fm = getSupportFragmentManager();
		ft = fm.beginTransaction();
		ft.replace(R.id.fragment_body, fragment, tag);
		ft.commit();
	}

	public void updateListKegMonthView() {
		monthViewFragment = (MonthViewFragment) getSupportFragmentManager()
				.findFragmentByTag(MonthViewFragment.TAG);
		if (monthViewFragment != null) {
			// monthView
			// Fragment.setIdRoom(_idRoom);
			Log.d(TAG, "monthfragment is not null");
			monthViewFragment.setListKeg(eventList);
		} else {
			dayViewFragment = (DayViewFragment) getSupportFragmentManager()
					.findFragmentByTag(DayViewFragment.TAG);
			if (dayViewFragment != null) {
				// dayFragment.setIdRoom(_idRoom);
				Log.d(TAG, "dayfragment is not null");
				dayViewFragment.setListKegiatan(eventList);
			}
		}

	}

	@Override
	public void onConnect(String message) {

	}

	private void setListEvent(JSONArray arrJsonCalEvent) {
		for (int i = 0; i < arrJsonCalEvent.length(); i++) {
			JSONObject jsonCalEvent;
			try {
				jsonCalEvent = arrJsonCalEvent.getJSONObject(i);

				CalendarEvent _ce = new CalendarEvent();
				_ce.setCalendarId(jsonCalEvent
						.getString(CalendarEvent.CALENDARID));
				_ce.setColor(jsonCalEvent.getString(CalendarEvent.COLOR));
				_ce.setDescription(jsonCalEvent
						.getString(CalendarEvent.DESCRIPTION));
				_ce.setEndTime(new Date(jsonCalEvent
						.getLong(CalendarEvent.ENDTIME)));
				_ce.setEventId(jsonCalEvent.getString(CalendarEvent.EVENTID));
				_ce.setId(jsonCalEvent.getInt(CalendarEvent.ID));
				_ce.setIsAllDayEvent(jsonCalEvent
						.getInt(CalendarEvent.ISALLDAYEVENT));
				_ce.setLocation(jsonCalEvent.getString(CalendarEvent.LOCATION));
				_ce.setOperatorId(jsonCalEvent.getInt(CalendarEvent.OPERATORID));
				_ce.setRecurringRule(jsonCalEvent
						.getInt(CalendarEvent.RECURRINGRULE));
				_ce.setStartTime(new Date(jsonCalEvent
						.getLong(CalendarEvent.STARTTIME)));
				_ce.setSubject(jsonCalEvent.getString(CalendarEvent.SUBJECT));

				if (_ce.getRecurringRule() == CalendarEvent.FLAG
						|| _ce.getRecurringRule() != CalendarEvent.UNFLAG) {
					JSONObject jsonRecDetail = jsonCalEvent
							.getJSONObject(RecurringDetail.TAG);
					RecurringDetail _rd = new RecurringDetail();
					_rd.setId(jsonRecDetail.getInt(RecurringDetail.ID));
					_rd.setIdEvent(jsonRecDetail
							.getInt(RecurringDetail.IDEVENT));
					_rd.setInterval(jsonRecDetail
							.getInt(RecurringDetail.INTERVAL));
					_rd.setType(jsonRecDetail.getString(RecurringDetail.TYPE));
					_rd.setUntil(new Date(jsonRecDetail
							.getLong(RecurringDetail.UNTIL)));
					_ce.setRecurringDetail(_rd);
				}

				JSONObject jsonCalList = jsonCalEvent
						.getJSONObject(CalendarList.TAG);
				CalendarList cl = new CalendarList();
				cl.setCalendarTitle(jsonCalList
						.getString(CalendarList.CALENDARTITLE));
				_ce.setCalendarList(cl);

				JSONObject jsonDosen = jsonCalEvent.getJSONObject(Dosen.TAG);
				Dosen d = new Dosen();
				d.setNama(jsonDosen.getString(Dosen.NAMA));
				d.setNotelp(jsonDosen.getString(Dosen.NOTELP));
				Guest g = new Guest();
				g.setDosen(d);
				_ce.setGuest(g);

				JSONObject jsonPengguna = jsonCalEvent
						.getJSONObject(Pengguna.TAG);
				Pengguna p = new Pengguna();
				p.setNama(jsonPengguna.getString(Pengguna.NAMA));
				p.setNoTelp(jsonPengguna.getString(Pengguna.NOTELP));
				_ce.setPengguna(p);

				eventList.add(_ce);
			} catch (JSONException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		updateListKegMonthView();
	}
	
	@Override
	public void onMessage(String message) {
		try {
			Log.d(CalViewAct.class.getName(), message);
			JSONObject msg = new JSONObject(message);
			String msgCode = msg.getString(MsgCode.MSGCODE);
			if (msgCode.equals(MsgCode.CALENDARLISTRES)) {
				calList = new ArrayList<CalendarList>();
				JSONArray arrJson = msg.getJSONArray(CalendarList.TAG);
				for (int i = 0; i < arrJson.length(); i++) {
					JSONObject jsonCalList = arrJson.getJSONObject(i);
					CalendarList _cl = new CalendarList();
					_cl.setId(jsonCalList.getInt(CalendarList.ID));
					_cl.setCalendarId(jsonCalList
							.getString(CalendarList.CALENDARID));
					_cl.setCalendarTitle(jsonCalList
							.getString(CalendarList.CALENDARTITLE));
					_cl.setJenis(jsonCalList.getString(CalendarList.JENIS));
					_cl.setKapasitas(jsonCalList.getInt(CalendarList.KAPASITAS));
					calList.add(_cl);
				}
				if (calList.size() > 0) {
					if (idSelectedCalList == "-1") {
						idSelectedCalList = calList.get(0).getCalendarId();
					}
					supportInvalidateOptionsMenu();
					sendReqEventByRoom(idSelectedCalList);
				} else {
					// setListRoom("-1");
				}
			} else if (msgCode.equals(MsgCode.CALENDAREVENTRES)) {
				eventList = new ArrayList<CalendarEvent>();
				JSONArray arrJsonCalEvent = msg.getJSONArray(CalendarEvent.TAG);
				setListEvent(arrJsonCalEvent);
			} else if (msgCode.equals(MsgCode.DOSENRES)) {
				listDosen = new ArrayList<Dosen>();
				JSONArray arrJsonDosen = msg.getJSONArray(Dosen.TAG);
				for (int i = 0; i < arrJsonDosen.length(); i++) {
					JSONObject jsonDosen = arrJsonDosen.getJSONObject(i);
					Dosen _d = new Dosen();
					_d.setEmail(jsonDosen.getString(Dosen.EMAIL));
					_d.setId(jsonDosen.getInt(Dosen.ID));
					_d.setJenisKelamin(jsonDosen.getString(Dosen.JENISKELAMIN));
					_d.setNama(jsonDosen.getString(Dosen.NAMA));
					_d.setNotelp(jsonDosen.getString(Dosen.NOTELP));
					listDosen.add(_d);
				}
			} else if (msgCode.equals(MsgCode.NEWCALEVENT)) {
				if (eventList != null) {
					JSONArray arrJsonCalEvent = msg
							.getJSONArray(CalendarEvent.TAG);
					setListEvent(arrJsonCalEvent);
				}
			} else if (msgCode.equals(MsgCode.NEWDELEVENT)) {
				if (eventList != null) {
					CalendarEvent _ce = new CalendarEvent();
					_ce.setId(msg.getInt(CalendarEvent.ID));
					_ce.setRecurringRule(msg
							.getInt(CalendarEvent.RECURRINGRULE));

					Iterator<CalendarEvent> setIterator = eventList.iterator();
					while (setIterator.hasNext()) {
						CalendarEvent ce = setIterator.next();
						if (_ce.getRecurringRule() == CalendarEvent.FLAG) {
							if (ce.getId() == _ce.getId()
									|| ce.getRecurringRule() == _ce.getId()) {
								setIterator.remove();
							}
						} else if (_ce.getRecurringRule() == CalendarEvent.UNFLAG) {
							if (ce.getId() == _ce.getId()) {
								setIterator.remove();
							}
						} else {
							if (ce.getRecurringRule() == _ce.getRecurringRule()
									|| ce.getId() == _ce.getRecurringRule()) {
								setIterator.remove();
							}
						}
					}
					updateListKegMonthView();
				}
			} else if (msgCode.equals(MsgCode.MSGCONFIRM)) {
				Toast.makeText(getApplicationContext(),
						msg.getString(MsgCode.MSGCONTENT), Toast.LENGTH_LONG)
						.show();
			}
		} catch (JSONException e) {
			e.printStackTrace();
		}
	}

	private void sendReqEventByRoom(String idCalList) {
		JSONObject msg = new JSONObject();
		try {
			msg.put(MsgCode.MSGCODE, MsgCode.CALENDAREVENTREQ);
			msg.put(CalendarEvent.CALENDARID, idCalList);
			Log.d(TAG, msg.toString());
			wsClient.sendTextMessage(msg.toString());
		} catch (JSONException e) {
			e.printStackTrace();
		}
	}

	@Override
	public void onMessage(byte[] data) {
		// Log.d(TAG, "byte msg : " + new String(data));
	}

	@Override
	public void onDisconnect(String reason) {
		Toast.makeText(this, "Disconnect from server", Toast.LENGTH_LONG)
				.show();
		logout(getWindow().getDecorView().findViewById(android.R.id.content));
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();
		if (wsClient.isConnected()) {
			// Log.d(TAG, "remove clientlistener");
			wsClient.removeListener(this);
		}
	}

	public boolean onKeyDown(int keyCode, KeyEvent keyEvent) {
		if (keyCode == KeyEvent.KEYCODE_BACK) {
			logout(getWindow().getDecorView()
					.findViewById(android.R.id.content));
			return true;
		}
		return false;
	}

	private void logout(View v) {
		wsClient.removeListener(this);
		wsClient.closeConnection();
		Intent i = new Intent(v.getContext(), LoginActivity.class);
		v.getContext().startActivity(i);
		finish();
	}

	@Override
	public void onError(Exception error) {

	}


}
